home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-03
/
advbas9b.zip
/
ADVBAS.DOC
< prev
next >
Wrap
Text File
|
1990-03-09
|
93KB
|
2,982 lines
ADVBAS Copyright (c) 1985-1990 Thomas G. Hanlin III
Advanced Function Library for BASIC Compilers
ADVBAS v99B, 03/09/90
Thomas G. Hanlin III
3544 E. Southern Ave. #104
Mesa, AZ 85204
Requirements:
An IBM PC/XT/AT/386 or compatible with the Microsoft BASIC compiler v6.x or
QuickBASIC v4.0-4.5. PC-DOS/MS-DOS versions 2.0 or higher should be used.
Some routines may require a PC-AT or compatible, as noted. Please read the
Operation Notes for more information on the subject.
This library and associated files are protected by copyright. However, it
may be distributed subject to the restrictions given below. The source code
is no longer available, although I will still provide support insofar as
regards bug fixes and so forth.
While ADVBAS is full-featured and is not crippled in any way, I'd like you to
consider it as a sample of the features contained in the commercial version
of the library, ProBas. You may use ADVBAS subject to the restrictions
below, but if you find ADVBAS useful, you might well want to upgrade to
ProBas. The ProBas library comes with tutorial and reference manuals, is a
much more professional product, and contains about four times as many
routines as provided by the ADVBAS library. See the PROBAS.DOC file for more
information about ProBas and related products.
Copying and Distribution:
The ADVBAS library may be copied and distributed freely under the following
conditions:
1) The source code, if you have it, MAY NOT BE DISTRIBUTED.
2) No fee of over $10.00 U.S. may be charged. This applies specifically
to physical copies and is not meant to prevent distribution by
telecommunications services.
3) All files must be included in their original and unmodified condition.
This includes ADVBAS.BS, ADVBAS.DOC, ADVBAS.ERR, ADVBAS.LIB,
ADVBAS.NEW, ADVBAS.QB4, ADVBAS.QRF, ADVBAS.XRF, COMBLINE.BAS,
FILES.LST, MONKEY.BAS, OBJECT.ZIP, PROBAS.TXT, READ.ME, and XREF.BAS.
The copyright is intended to preserve my options and to protect you from the
untoward modifications of others. It is not intended to prevent the public
distribution of ADVBAS, subject to the above limitations.
Caveats:
These routines have not caused me any problems and seem to be fully
operational. However, I will not be responsible for any damages caused by
the use, misuse, or inability to use ADVBAS. If you run into a problem,
please let me know, and I will do my best to verify and fix the trouble.
Introduction:
The BASIC Compiler is a powerful and flexible tool. However, it suffers from
a number of limitations. It is difficult to access many of the capabilities
of DOS, features which require error trapping can't readily be used in
subprograms, and the speed is not all that it might be, for all its
improvement over interpreted BASIC. The size of compiled programs tends to
be rather excessive as well.
In order to reduce these problems, I've designed a number of assembly
language routines which perform various functions and put them in a library
which can be accessed by compiled BASIC programs. Since I've found these
routines to be useful, I thought I'd pass them on to other people. You may
use ADVBAS routines in any of your programs, whether commercial, for the
public domain, or simply for your own private use. I'd appreciate it if you
acknowledged the use of these routines in your program or documentation, but
that is not required.
Support:
Since the release of the commercial version of the library, ProBas, I am not
accepting any further registrations. Support is hence limited to bug fixes
and so forth, except for previously-registered users. If you have any
problems, please read this manual. It probably contains the answer to your
questions. If not, you can reach me via U.S. mail or the FidoNet QuickBASIC
BBS network. Please do not phone.
Miscellaneous Notes:
THE ROUTINES IN THIS VERSION OF ADVBAS ARE NOT ALL COMPATIBLE WITH THOSE IN
PREVIOUS RELEASES OF ADVBAS.
This version of the ADVBAS library has been updated specifically to work with
QuickBASIC 4.x. Due to changes made by Microsoft, the routines that use
arrays must be handled differently. Any such routines have new calling
conventions, so if you have used the ADVBAS array routines previously, you
will have to modify your programs somewhat. The new routines will not work
with QuickBASIC versions prior to 4.0.
If you need a library that will work with any version of QuickBASIC, rather
than just those versions that ADVBAS supports, you should look into the
ProBas library. It is designed to work with any IBM or Microsoft version of
the BASIC compiler. Borland's Turbo BASIC is not supported, as it does not
provide for external libraries.
ProBas provides, among other things, routines for sorting, EGA and VGA
graphics, handling of PC Paintbrush graphics files, "long" integer support
(even with compiler versions before QuickBASIC 4.0 and BASCOM 6.0), virtual
screen handling, expanded and extended memory support, and much more. Add-on
toolkits provide menus (ring, bar, pull-down, pop-up, you name it), btree
file indexing, telecommunications support (file transfers, dialer, script
language, etc), online hypertext help systems, screen design, and just about
anything else you can think of. For more information, see PROBAS.DOC.
Using ADVBAS in the QuickBASIC environment:
In order to use ADVBAS inside the QuickBASIC editor/environment, you must
convert the ADVBAS.LIB library to ADVBAS.QLB. This is done using the LINK
command like this:
LINK ADVBAS.LIB/Q,ADVBAS.QLB,NUL,BQLB40.LIB;
That's the syntax for QB 4.0. If you're using QB 4.0b or QB 4.1, change the
last library name to BQLB41.LIB. If you're using QB 4.5, make it BQLB45.LIB.
If in doubt, just get a DIRectory of your QuickBASIC library files, and use
the name of the BQLBxx.LIB file that appears.
Once you have created the ADVBAS.QLB library, you can access the ADVBAS
routines from the QB environment by starting it with the following syntax:
QB /L ADVBAS
Optionally, you may choose to load your program when you start QuickBASIC.
That looks like this:
QB program /L ADVBAS
...where "program" is the name of your BASIC program.
Note that there is a bug in QuickBASIC 4.0 - 4.1 which causes it to create
unduly large .EXE files when you choose the editor option "compile to EXE".
This does not affect compiling from the command line and is only a problem if
you create your .EXE file from the editor/environment. This bug was fixed
with the release of QuickBASIC 4.5.
Compiling from the command line:
You can use ADVBAS routines in your program even if you compile from the
command line rather than from within the editor/environment. To do so,
compile your program as you usually do. That should look something like:
BC program;
Next, you LINK the program, but using a special syntax so that the ADVBAS
routines are joined to your program:
LINK program,,NUL,ADVBAS;
This tells the LINKer that your program uses ADVBAS routines. LINK will then
search through the ADVBAS library and join the appropriate routines with your
program. Only the routines that you actually use will become part of your
program.
Other languages:
The current version of ADVBAS is written using the Microsoft interlanguage
calling conventions. It should be possible to use most or all ADVBAS
routines with Microsoft C and Microsoft Pascal by making the proper
declarations in your program. For Microsoft C, tell the compiler that ADVBAS
uses the Pascal calling convention.
The Quick C compiler should be able to use ADVBAS in the same way as
Microsoft C. This does not apply to QuickPascal, however, which (strangely
enough) does not support normal libraries. Instead, QuickPascal follows
Borland's Turbo Pascal convention and uses "units". This convention is not
compatible with ADVBAS.
BASIC compilers other than those from Microsoft are not supported, since they
do not use the same calling conventions. I would expect that ADVBAS will
work with C compilers that support the Microsoft calling convention, however.
Operation Notes
Requirements:
Numeric values used with these routines must be integers unless specified
otherwise. Make sure the variables are integers using DEFINT, or add a
percent sign ("%") to the end of the variable name. If you use a numeric
expression rather than a variable, it might be a good idea to use the CINT
function to insure that the result is an integer.
Strings must sometimes be defined to a certain minimum length, since assembly
language routines are not permitted to change the length of strings. When
strings are returned, the length of the string will usually also be returned
so that you can convert the result to the appropriate length. Some strings,
like those containing filenames, must be terminated by a CHR$(0).
Arrays require special treatment. Rather than passing the array directly,
you must pass the segment and offset of the array. This is accomplished by
using the QuickBASIC VARSEG and VARPTR functions, as described in the
descriptions of the routines which use arrays. Note that you may use either
Dynamic or Static arrays. Normal variable-length string arrays cannot be
used, although fixed-length string arrays, user-defined TYPEs, and numeric
arrays are all acceptable. Just make sure that the array or TYPEd variable
is of an adequate length if you use a routine which expects a specific amount
of storage. To save the screen with SCRSAVE, for example, you need at least
4,000 bytes of storage space. This can be obtained by passing an array or
TYPEd variable dimensioned in any of the following ways:
DIM Scrn%(1 TO 2000) ' 4,000 bytes of integer storage
DIM Scrn&(1 TO 1000) ' 4,000 bytes of long integer storage
DIM Scrn AS STRING * 4000 ' 4,000 bytes of fixed-length string storage
Compatibility:
These functions vary in what they demand of your computer. Some functions
will work only on true clones, some will work on near clones, and some will
work on any MS-DOS machine. The compatibility level of each function is
listed using the categories CLONE (will work on hardware compatibles only),
BIOS (close compatibles only), DOS (any MS-DOS machine), and ANY (hardware
independent). Note that the BASIC compiler itself does not produce very
compatible code (BASIC video routines are CLONE level, for example), so
you should have no problems with ADVBAS compatibility if you can use the
BASIC compiler.
Routine Reference
Disk:
CopyFile copy a file
DelSub delete a subdirectory
DiskStat retrieve assorted disk status information
DrvSpace get the space left on a given drive
Exist see if a file exists
FClose close a file
FCreate create a file
FindFirstF find the first file matching a wildcard specification
FindNextF find additional files after FindFirstF
FOpen open a file
FRead read from a file
FSetEnd move to the end of a file
FSetRec move to a specific point in a file
GetAttrF get the attribute of a file found by FindFirstF/FindNextF
GetDateF get the date of a file found by FindFirstF/FindNextF
GetDrv get the default drive
GetFAttr get the attribute of a file
GetFDate get the date of a file
GetFTime get the time of a file
GetNameF get the name of a file found by FindFirstF/FindNextF
GetSizeF get the size of a file found by FindFirstF/FindNextF
GetSub get the default subdirectory
GetTimeF get the time of a file found by FindFirstF/FindNextF
MakeSub create a subdirectory
MLoad a fast version of the BLOAD statement
SetDrv set the default drive
SetFTD set the time and date of a file
SetFAttr set the attribute of a file
SetSub set the default subdirectory
SubExist see if a subdirectory exists
Input:
ClrKbd clear the keyboard buffer
DosInkey get a key using DOS standard input
GetKbd get the state of the keyboard toggles
GetKey get one of a list of valid keys
KeyPress see if a key has been pressed
MmButton see if the mouse buttons are being pressed
MmCheck see if a mouse is available
MmClick see if the mouse buttons were pressed since last checked
MmCursorOff make the mouse cursor invisible
MmCursorOn make the mouse cursor visible
MmGetLoc get the location of the mouse cursor
MmSetLoc set the location of the mouse cursor
MmSetRange set the range for the mouse cursor
SetKbd set the state of the keyboard toggles
Routine Reference
String:
BSq compress a text string
BUsq uncompress a string
BUsqLen see how long a compressed string will be when expanded
Checksum calculate an Xmodem/Ymodem checksum
CRC calculate an Xmodem/Ymodem CRC
Crunch remove duplicates of a character from a string
DateN2S convert a date from numbers to a string
DateS2N convert a date from a string to numbers
Extract extract a substring from within a delimited string
LoCase convert the letters in a string to lowercase
LRotate rotate the characters in a string left
MultiAnd perform an arithmetic AND operation on each char in a string
MultiOr perform an arithmetic OR operation on each char in a string
MultiXor perform an arithmetic XOR operation on each char in a string
Reverse reverse the characters in a string
RRotate rotate the characters in a string right
Soundex get the Soundex code for a string (for sound-alike matching)
StripBlanks remove leading and/or trailing blanks from a string
Strip remove occurrences of a specific character from a string
StripRange remove occurrences of a range of characters from a string
TimeN2S convert a time from numbers to a string
TimeS2N convert a time from a string to numbers
Tinstr find a given type of character within a string
UpCase convert the letters in a string to uppercase
Xlate translate the characters of a string using a table
Array:
AddMatI add a value to selected elements of an integer array
ReadBitF get a number from an array of arbitrary bit length
SetMatI set selected elements of an integer array to a specific value
WriteBitF put a number into an array of arbitrary bit length
Routine Reference
Video:
BkScroll scroll any part of the screen down, or clear it
BkSpace destructive backspace
CalcAttr calculate color/attribute from foreground and background colors
ClrEOL clear from the cursor to the end of the line
DelChr delete a character
DmPrint display a string using DOS output
GetCRT get display type (mono or color)
GetLine retrieve a specified line from a saved screen
GetScreen save any part of any display page to a buffer
InsChr insert a space
MakeWindow display a pop-up window
MDelChr delete a character from a window defined by MWindow
MInsChr insert a space into a window defined by MWindow
MPrint display a string to a window defined by MWindow
MPrintC display a character to a window defined by MWindow
MWindow define the range for certain display operations
PrintScreen print out the display to the default printer
QPrint display a string very quickly using machine-level access
ReColor change everything of a specific color to another color
ResetPoint clear a point (low-resolution text-mode graphics)
Scroll scroll any part of the screen up, or clear it
ScrRest restore a saved screen to the display
ScrRestP restore a saved screen to a specific display page (no snow)
ScrRestPD restore a saved screen to a specific display page
ScrSave save the contents of the screen to a buffer
ScrSaveP save a specific display page to a buffer (no snow)
ScrSavePD save a specific display page to a buffer
SetPoint set a point (low-resolution text-mode graphics)
TestPoint test a point (low-resolution text-mode graphics)
XQPrint display a string very quickly using machine-level access
Miscellaneous:
Any2Dec convert from any base to decimal
BlockMove move data from one area of memory to another
Carrier get the state of the modem Carrier Detect signal
DataSeg get the default Data Segment
Date2Int compress a date into an integer
Dec2Any convert from decimal to any base
Delay delay for a given number of seconds
Delay18th delay for a given number of eighteenths of seconds
DTR set the state of the comm port's DTR signal
Equipment get hardware info about memory and installed ports
GetDOSv get the current DOS version
GetExtM get the amount of extended memory (AT systems only)
GetLIMm get the amount of expanded memory installed and available
Int2Date uncompress a date from an integer
Int2Time uncompress a time from an integer
Month get the name of a month
SetComm set up comm parameters without closing the comm port
ShiftL shift the bits in an integer left
ShiftR shift the bits in an integer right
Speaker turn sound effects on or off
Time2Int compress a time into an integer
WeekDay get the day of the week
Compatibility Chart
The following will work on ANY machine:
AddMatI, Any2Dec, BlockMove, Bsq, BUsq, BUsqLen, CalcAttr, Checksum, CRC,
Crunch, DataSeg, Date2Int, Dec2Any, Extract, GetLine, Int2Date, Int2Time,
LoCase, LRotate, Month, MultiAND, MultiOR, MultiXOR, ReadBitF, Reverse,
RRotate, SetMatI, ShiftL, ShiftR, Soundex, Strip, StripBlanks, StripRange,
Time2Int, TInstr, UpCase, WriteBitF, Xlate
The following will work on machines that can run DOS:
CopyFile, DelSub, DiskStat, DmPrint, DOSInkey, DrvSpace, Exist, FClose,
FCreate, FindFirstF, FindNextF, FOpen, FRead, FSetEnd, FSetRec, FWrite,
GetAttrF, GetDateF, GetDOSv, GetDrv, GetFAttr, GetFDate, GetFTime, GetNameF,
GetSizeF, GetSub, GetTimeF, MakeSub, MLoad, SetDrv, SetFAttr, SetFTD, SetSub,
SubExist, WeekDay
The following will work on machines with a PC-type BIOS (* for AT BIOS):
BkScroll, BkSpace, ClrKbd, ClrEOL, DateN2S, DateS2N, Delay, Delay18th,
Equipment, GetCRT, GetExtM*, GetKey, GetLIMm, Keypress, MDelChr, MInsChr,
MmButton, MmCheck, MmClick, MmCursorOff, MmCursorOn, MmGetLoc, MmSetLoc,
MmSetRange, MPrint, MPrintC, MWindow, PrintScreen, ResetPoint, SetPoint,
Scroll, TestPoint, TimeN2S, TimeS2N, XmPrint
The following will work only on true PC compatibles:
Carrier, DelChr, DTR, GetKbd, GetScreen, InsChr, MakeWindow, PutScreen,
QPrint, ReColor, ScrRest, ScrRestP, ScrRestPD, ScrSave, ScrSaveP, ScrSavePD,
SetComm, SetKbd, Speaker, XQPrint, XQPrintD
Note that routines from higher sections will work on machines from lower
sections (DOS-level routines will work on BIOS-level and CLONE-level
machines). It doesn't work the other way around (CLONE-level routines may
not work on a DOS-level machine).
Name: AddMatI
Type: Miscellaneous / ANY
Description:
Adds a scalar (integer) value to an integer array. You can subtract by
adding a negative number. If the results of the calculation ever go
outside integer range (-32768 to 32767), the overflow flag is set on
return. See SETMATI for more information.
Example:
DIM Array%(1 TO 10000)
' presumably you set Array%() to something here
ArraySize% = UBOUND(Array%) - LBOUND(Array%) + 1
DSeg% = VARSEG(Array%(LBOUND(Array%)))
DOfs% = VARPTR(Array%(LBOUND(Array%)))
AddValue% = -6
CALL AddMatI(DSeg%, DOfs%, ArraySize%, AddValue%, Overflow%)
IF Overflow% THEN PRINT "Error: overflow during array operation"
Name: Any2Dec
Type: Miscellaneous / ANY
Description:
Converts a number (in string form) from any base (2-35) to a decimal
integer (base 10). The number to be converted may be in either signed
integer range (-32768 to 32767) or unsigned integer range (0 to 65535).
It is converted to a signed integer, since BASIC doesn't have an unsigned
integer type. If you would prefer to treat the results as an unsigned
integer, use a long integer value to receive the result, after setting it
to zero.
Example:
' for a signed integer result, do this:
INPUT "Number, base of number"; Number$, NumBase%
CALL Any2Dec(Number$, NumBase%, Result%, ErrCode%)
IF ErrCode% THEN
PRINT "Invalid number for specified base"
ELSE
PRINT "In decimal, that number is: "; Result%
END IF
' for an unsigned result, do this:
INPUT "Number, base of number"; Number$, NumBase%
Result& = 0
CALL Any2Dec(Number$, NumBase%, Result&, ErrCode%)
IF ErrCode% THEN
PRINT "Invalid number for specified base"
ELSE
PRINT "In decimal, that number is: "; Result&
END IF
Name: BkScroll
Type: Video / BIOS
Description:
Scrolls any selected part of the screen down by a specified number of
lines. If you tell it to scroll zero lines, the specified area will be
cleared instead.
Example:
TopRow% = 1
LeftCol% = 1
BottomRow% = 25
RightCol% = 80
Times% = 2
CALL BkScroll(LeftCol%, TopRow%, RightCol%, BottomRow%, Times%)
' scrolls the entire screen down two lines
Name: BkSpace
Type: Video / BIOS
Description:
This is a "destructive backspace" routine. It deletes the previous
character and moves the cursor back one space. If the cursor was at the
beginning of a line, it will wrap up to the end of the previous line if
there is one. Since QuickBASIC may not recognize the change of cursor
position, the new cursor position is returned so that you can use the
LOCATE statement.
Example:
CALL BkSpace(Col%, Row%) ' note that the coordinates are backward!
LOCATE Row%, Col%
Name: BlockMove
Type: Miscellaneous / ANY
Description:
Copies information from one area of memory to another. Due to certain
convolutions involved, it is not recommended that you use this routine
unless you have a very good idea of what you're doing. It isn't as easy
as it looks! Specify a direction of zero to move forward from the
specified addresses, or a nonzero direction to move backward from the
specified addresses.
Example:
FromSeg% = &HB800 ' location of CGA text page 0
FromOfs% = 0
ToSeg% = &HB800 ' location of CGA text page 1
ToOfs% = &H1000
Bytes% = 4000 ' 4,000 bytes per 80x25 screen
Direction% = 0 ' increment addresses as we move
CALL BlockMove(FromSeg%, FromOfs%, ToSeg%, ToOfs%, Bytes%, Direction%)
' we just copied CGA page 0 to page 1
Name: BSq
Type: String / ANY
Description:
Reduces the length of text strings by using several techniques to compress
blanks. The strings may not be longer than 127 characters or contain IBM
ASCII characters (from CHR$(128) to CHR$(255)). The result will be a
string that is printable, if odd looking (it will contain IBM ASCII
codes, which normally show up as graphics characters). Space savings
range from about 16% on normal text to 50% or more for strings which
contain many spaces. The resulting string might be the same length, if it
didn't contain any blanks, but it will never be longer than the original.
Example:
INPUT "String to squeeze"; St$
CALL BSq(St$, SLen%)
PRINT "Squeezed string: "; LEFT$(St$, SLen%)
Name: BUsq
Type: String / ANY
Description:
Unsqueezes a string that was compressed by BSq. Use the BUsqLen routine
beforehand to find out how long the resulting string will be.
Example:
see the BUsqLen routine
Name: BUsqLen
Type: String / ANY
Description:
Tells how long a string compressed by BSq will be, once it is unsqueezed.
This is necessary before unsqueezing the string with BUsq.
Example:
CALL BUsqLen(St$, SLen%)
IF SLen% < 0 THEN
PRINT "Error: string was not compressed or is damaged"
ELSE
Unsq$ = SPACE$(SLen%)
CALL BUsq(St$, Unsq$)
END IF
Name: CalcAttr
Type: Video / ANY
Description:
Calculates the color/attribute for certain display routines, such as
XQPrint. A color/attribute is a single byte that combines the foreground
and background colors together. It represents the way colors are handled
by the computer at the BIOS and direct machine level.
Example:
ForeGround% = 15 ' bright white foreground color
BackGround% = 0 ' black background color
CALL CalcAttr(ForeGround%, BackGround%, Attr%)
Name: Carrier
Type: Miscellaneous / CLONE
Description:
Returns the status of the modem Carrier Detect signal. You may specify
communications port one or two.
Example:
CommPort% = 1
CALL Carrier(CommPort%, CD%)
IF CD% THEN
PRINT "Carrier detected"
ELSE
PRINT "No carrier"
END IF
' Note: we don't use the variable Carrier% as QuickBASIC would complain.
' QB doesn't like it when variables and routines have the same name.
Name: CopyFile
Type: Disk / DOS
Description:
Copies a file. This is faster than the DOS command and doesn't have the
overhead of using the SHELL statement. You might want to use the Exist
routine to see if the destination file exists beforehand, in order to
avoid accidentally copying over an existing file.
Example:
SourceFile$ = "A:EXAMPLE.TXT"
DestFile$ = "C:\DOCUMENT\EXAMPLE.TXT"
CALL CopyFile(SourceFile$ + CHR$(0), DestFile$ + CHR$(0), ErrCode%)
IF ErrCode% THEN
PRINT "Error: copy failed"
' this will usually be due to a nonexistent source file
' or to running out of space on the destination disk
END IF
Name: Checksum
Type: Miscellaneous / ANY
Description:
Calculates a checksum for a string. This is the same checksum as used by
the standard Xmodem file transfer protocol. It will also work with any
proper implementation of Ymodem.
Example:
CALL Checksum(St$, Chk%)
Name: ClrEOL
Type: Video / BIOS
Description:
Clears from the cursor position to the end of the current screen row,
inclusive. The cursor is not moved.
Example:
CALL ClrEOL
Name: ClrKbd
Type: Input / BIOS
Description:
Clears the keyboard buffer. Any keys which were waiting to be processed
will be gone. This is a particularly useful routine to use before an
input routine used to clear up an error condition, for example. It
insures that keys waiting in the type-ahead buffer do not unexpectedly
answer for the user.
Example:
CALL ClrKbd
INPUT "File does not exist. Create it (Y/N)"; YN$
Name: CRC
Type: Miscellaneous / ANY
Description:
Calculates a CRC (Cyclical Redundancy Check) for a string. This is used
for error detection. The algorithm used is compatible with the Xmodem CRC
and Ymodem CRC file transfer protocols.
Example:
' sending an Xmodem or Ymodem record (St$ is the data part):
CALL CRC(St$ + STRING$(2, 0), HiCRC%, LoCRC%)
St$ = St$ + CHR$(HiCRC%) + CHR$(LoCRC%)
' receiving an Xmodem or Ymodem record:
' (St$ is the data part plus the received CRC)
CALL CRC(St$, HiCRC%, LoCRC%)
IF HiCRC% = 0 AND LoCRC% = 0 THEN
St$ = LEFT$(St$, LEN(St$) - 2) ' trim off received CRC
GoodRecord = -1 ' flag it as a good record
ELSE
GoodRecord = 0 ' flag it as a bad record
END IF
Name: Crunch
Type: String / ANY
Description:
Crunches duplicates of a given character in a string down to a single
character. This is a good way to get input into a regular format,
especially when combined with the StripBlanks routine.
Example:
St$ = "This is a test"
Ch$ = " "
CALL Crunch(St$, Ch$, SLen%)
St$ = LEFT$(St$, SLen%)
' the result here will be "This is a test"
Name: DataSeg
Type: Miscellaneous / ANY
Description:
Gets the default data segment, which is used by BASIC for storing
variable-length strings. It is also used for storing static arrays,
except when in the QB editor/environment. This can be handy in
conjunction with the BlockMove routine.
Example:
CALL DataSeg(DSeg%)
Name: Date2Int
Type: Miscellaneous / ANY
Description:
Compresses a date into an integer. The date is assumed to be valid. The
year should be within the range 1900 - 2026 (or 0 - 99, which is assumed
to represent 1900 - 1999). The resulting compressed date is not in
"Julian" form (performing mathematical operations on it will not get you
anywhere).
Example:
CALL Date2Int(Mnth%, Day%, Year%, Result%)
' we abbreviate the month since there is a routine named Month and
' QuickBASIC would complain if we had a variable by the same name.
Name: DateN2S
Type: String / ANY
Description:
Converts a date from numeric form to a string. The year may be any
non-negative number. You must reserve at least eight characters for the
string.
Related routines:
DateS2N, TimeN2S, TimeS2N
Example:
Mnth% = 3
' we abbreviate the month since there is a routine named Month and
' QuickBASIC would complain if we had a variable by the same name.
Day% = 2
Year% = 1987 ' 87 would do as well
Result$ = SPACE$(8)
CALL DateN2S(Mnth%, Day%, Year%, Result$)
' the result from this will be "03/02/87"
' if you prefer the form "03-02-87", add the following:
MID$(Result$, 3, 1) = "-"
MID$(Result$, 6, 1) = "-"
Name: DATES2N
Type: String / ANY
Description:
Converts a date from a string to numeric form. The date string may be in
either the BASIC format ("02-01-1990") or the usual format ("02/01/90").
Example:
CALL DateS2N(Mnth%, Day%, Year%, DATE$)
' we abbreviate the month since there is a routine named Month and
' QuickBASIC would complain if we had a variable by the same name.
Name: Dec2Any
Type: Miscellaneous / ANY
Description:
Converts a number to any reasonable base (2-35). The number will be
converted to an unsigned integer, in keeping with the operation of the
BASIC functions HEX$ and OCT$. It is recommended that you set the result
string to at least 16 characters, which is the maximum possible length
that can be returned by this routine. The result will be right-justified
in the string that you provided, so if you want leading zeroes, just set
the initial string to zeroes and ignore the returned length specification.
Example:
INPUT "Decimal number, to base"; Number%, NumBase%
Result$ = STRING$(16, "0")
CALL Dec2Any(Number%, NumBase%, Result$, RLen%)
IF RLen% < 0 THEN
PRINT "Error: invalid base or insufficient room in result string"
ELSE
Result$ = RIGHT$(Result$, RLen%)
PRINT "Result: "; Result$
END IF
Name: Delay
Type: Miscellaneous / BIOS
Description:
Delays for a specified number of seconds. This is based on the system
clock, so it will delay for the same amount of time no matter how fast
your computer may be. It is normally accurate to within 1/18th second,
although it may take longer if multitasking is going on.
Example:
Seconds% = 60
CALL Delay(Seconds%) ' delay for one minute
Name: Delay18th
Type: Miscellaneous / BIOS
Description:
Delays for a specified number of 18ths of a second. This is based on the
system clock, so it will delay for the same amount of time no matter how
fast your computer may be. It is normally accurate to within 1/18th
second, although it may take longer if multitasking is going on.
Example:
SmallDelay% = 9
CALL Delay18th(SmallDelay%) ' delay for 1/2 second
Name: DelChr
Type: Video / CLONE
Description:
Deletes the character at the specified screen location. All characters to
the right of it on the same row will be shifted left to fill the vacated
space. This works only in text mode (SCREEN 0) on display page zero.
Example:
Row% = CSRLIN
Col% = POS(0)
CALL DelChr(Row%, Col%) ' delete the character at the cursor
Name: DelSub
Type: Disk / DOS
Description:
Deletes a subdirectory. Note that you may not delete a subdirectory if
there are any files in it or if it is the current directory. The root
directory may never be deleted.
Example:
CALL DelSub(SubDir$ + CHR$(0), ErrCode%)
IF ErrCode% THEN
PRINT "Error: unable to delete subdirectory "; SubDir$
END IF
Name: DiskStat
Type: Disk / DOS
Description:
Gets various status information about a given disk drive. You may use an
at-sign ("@") to specify the default drive. The information returned will
be free clusters, total clusters, bytes per sector, and sectors per
cluster. From this, you can calculate the amount of space left on the
disk, the amount of space used, and so forth.
Example:
Drive$ = "C"
CALL DiskStat(Drive$, FreeClus%, TotClus%, BytesPerSec%, SecsPerClus%)
FreeSpace& = CLNG(FreeClus%) * CLNG(BytesPerSec%) * CLNG(SecsPerClus%)
TotalSpace& = CLNG(TotClus%) * CLNG(BytesPerSec%) * CLNG(SecsPerClus%)
PRINT "Information for drive "; Drive$; ":"
PRINT " Total bytes:"; TotalSpace&
PRINT " Bytes free :"; FreeSpace&
PRINT " Bytes used :"; TotalSpace& - FreeSpace&
Name: DmPrint
Type: Video / DOS
Description:
Displays a string at the current cursor position, using DOS display
methods. This allows full redirection (unlike PRINT, this routine will
work properly with windowing multitaskers and CTTY), use of ANSI.SYS, and
so forth. Control codes are largely treated in the standard ASCII way
rather than the way BASIC handles them. The cursor position may or may
not be updated, depending on your version of QuickBASIC.
Example:
CALL DmPrint(St$)
Name: DOSInkey
Type: Keyboard / DOS
Description:
Like INKEY$, but gets a key from the standard input device. This is
normally the keyboard, but it may be redirected to a file or to a comm
port (using CTTY). Two parameters are returned. The first gives the key
code, if any, and the second gives status information. See example.
Example:
CALL DOSInkey(ChrCode%, ChrType%)
IF ChrType% = 0 THEN
PRINT "No key is pressed"
ELSEIF ChrType% = 1 THEN
PRINT "The "; CHR$(ChrCode%); " key was pressed."
ELSE
PRINT "An extended key was pressed. The code is "; ChrCode%
' this will happen for function keys, ALT key combinations, etc
' ChrCode% is the same as the right char of a two-char INKEY$ string
END IF
Name: DrvSpace
Type: Disk / DOS
Description:
Gets the amount of free space remaining on the specified drive. You may
use an at-sign ("@") to specify the default drive. See also DiskStat.
Example:
Drive$ = "@" ' use the default drive
CALL DrvSpace(Drive$, A%, B%, C%)
FreeSpace& = CLNG(A%) * CLNG(B%) * CLNG(C%)
Name: DTR
Type: Miscellaneous / CLONE
Description:
Turns the communications signal DTR (Data Terminal Ready) on or off.
Turning the DTR off is a reliable way of making most modems drop carrier
(hang up the phone). Use zero to turn off the DTR, or nonzero to turn it
back on. The comm port must be one or two.
Example:
CommPort% = 1
DTRstate% = 0 ' turn off the DTR
CALL DTR(CommPort%, DTRstate%)
Name: Equipment
Type: Miscellaneous / BIOS
Description:
Gets information about the basic hardware configuration of the computer:
base memory, parallel ports, serial ports, and game ports. Note that some
computers will not return accurate information about the game port.
Example:
CALL Equipment(KBytes%, Parallel%, Serial%, Game%)
Name: Exist
Type: Disk / DOS
Description:
Sees if a specified file exists. You may prefer to use the FindFirstF
routine instead if you are operating in a multitasking or network
environment, to avoid possible conflicts.
Example:
CALL Exist(File$ + CHR$(0), FileExists%)
IF FileExists% THEN PRINT "File already exists"
Name: Extract
Type: String / ANY
Description:
Extracts a substring from a delimited string. You must specify which of
the delimited substrings to return (1-256) and the delimiter character.
A pointer to the start of the substring and the length of the substring
will be returned.
Example:
St$ = "John Doe/15 Maple Rd/Hometown, CA 99199/(300) 111-1111"
Index% = 2
Delimiter$ = "/"
CALL Extract(St$, Delimiter$, Index%, Start%, SLen%)
PRINT MID$(St$, Start%, SLen%)
' this will print "15 Maple Rd"
Name: FClose
Type: Disk / DOS
Description:
Closes a file that was opened using the FOpen routine.
Related routines:
FCreate, FOpen, FRead, FSetEnd, FSetRec, FWrite
Example:
CALL FClose(Handle%)
Name: Fcreate
Type: Disk / DOS
Description:
Creates a file with the specified attribute and opens it for read/write
access. If the file already existed, it's set to zero bytes in length.
The file attribute may be zero, to create a normal file, or two, to create
a hidden file. If there is no error, a "handle" is returned with which
you can access the file using other ADVBAS routines.
Related routines:
FOpen, FRead, FSetEnd, FSetRec, FWrite
Example:
Attr% = 0 ' normal file
CALL FCreate(File$ + CHR$(0), Attr%, Handle%, ErrCode%)
IF ErrCode% THEN PRINT "Error: unable to create file "; File$
Name: FindFirstF
Type: Disk / DOS
Description:
Finds the first file to match the file specification and search attribute
that you give it. The file specification may contain a drive and
directory. Wildcards are permitted. If there is no matching file,
ErrCode% will be nonzero.
The search attribute may be any combination of the following:
0 normal files
2 hidden and normal files
4 system and normal files
16 subdirectories and normal files
Add the desired attributes together to produce the search attribute. You
may retrieve various information about any matching file (see below).
Related routines:
FindNextF, GetAttrF, GetDateF, GetNameF, GetSizeF, GetTimeF
Example:
File$ = "*.*" ' match any file
Attr% = 16+2 ' seek subdirectories, hidden and normal files
CALL FindFirstF(File$ + CHR$(0), Attr%, ErrCode%)
IF ErrCode% THEN PRINT "No matching files"
Name: FindNextF
Type: Disk / DOS
Description:
This is used after the FindFirstF routine in order to find further
matching files.
Related routines:
FindFirstF, GetAttrF, GetDateF, GetNameF, GetSizeF, GetTimeF
Example:
CALL FindNextF(ErrCode%)
IF ErrCode% THEN PRINT "No more matching files"
Name: FOpen
Type: Disk / DOS
Description:
Opens an existing file for use with ADVBAS routines. If you want to
create a new file, use the FCreate routine instead.
You must specify the read/write mode:
0 open for reading
1 open for writing
2 open for reading and writing
You must also specify the sharing mode:
0 no file sharing is allowed
1 no other program may access the file while we're using it
2 no other program may write to the file while we're using it
3 no other program may read from the file while we're using it
4 other programs may read/write the file while we're using it
Sharing modes are important for multitasking and networking. You are
advised to use "Sharing% = 2" if you are only reading from a file, so that
you don't tie it up unnecessarily. The sharing mode will be ignored on
DOS versions prior to 3.0.
If there is no error, a "handle" will be returned with which you can
access the file using other ADVBAS routines.
Related functions:
FClose, FCreate, FRead, FSetEnd, FSetRec, FWrite
Example:
ReadWrite% = 0 ' open for reading
Sharing% = 2 ' allow other programs to read file at the same time
CALL FOpen(File$ + CHR$(0), ReadWrite%, Sharing%, Handle%, ErrCode%)
IF ErrCode% THEN PRINT "Error: unable to open file "; File$
Name: FRead
Type: Disk / DOS
Description:
Reads information from a file opened by FOpen or FCreate. You must
specify the file handle which was returned to you by the open routine.
You must also provide a buffer to hold the information that is read. This
buffer may be provided by an array, fixed-length string, or TYPEd
variable. The file pointer will be updated appropriately after the read.
A nonzero error code is returned if something went wrong. An error code
of negative one indicates that the end of the file was reached before all
of the specified bytes could be read. In that case, BytesRead% will tell
you how many bytes were actually read.
Related routines:
FClose, FCreate, FOpen, FSetEnd, FSetRec, FWrite
Example:
DIM Buffer AS STRING*512 ' 512-byte fixed-length string buffer
' somewhere in here you would use FOpen or FCreate to open a file
Bytes% = 512 ' read 512 bytes
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL FRead(Handle%, DSeg%, Dofs%, Bytes%, BytesRead%, ErrCode%)
IF ErrCode% THEN PRINT "Error reading from file"
Name: FSetEnd
Type: Disk / DOS
Description:
Sets the file pointer (of a file opened by FOpen or FCreate) to the end of
the file. This allows you to append information to the end of a file.
Related routines:
FClose, FCreate, FOpen, FRead, FSetRec, FWrite
Example:
CALL FSetEnd(Handle%)
Name: FSetRec
Type: Disk / DOS
Description:
Sets the file pointer (of a file opened by FOpen or FCreate) to a specific
record in the file. The next read from (or write to) the file will begin
at that point.
Related routines:
FClose, FCreate, FOpen, FRead, FSetEnd, FWrite
Example:
RecSize% = 128 ' 128 bytes per record
RecNum% = 34 ' record number 34
CALL FSetRec(Handle%, RecSize%, RecNum%)
Name: FWrite
Type: Disk / DOS
Description:
Writes information to a file opened by FOpen or FCreate. You must specify
the file handle which was returned to you by the open routine. You must
also provide the location of the buffer that holds the information to be
written. This buffer may be an array, fixed-length string, or TYPEd
variable. The file pointer will be updated appropriately after the write.
A nonzero error code is returned if something went wrong. In that case,
BytesWritten% will tell you the how many bytes were actually written.
Related routines:
FClose, FCreate, FOpen, FRead, FSetEnd, FSetRec
Example:
DIM Buffer AS STRING*512 ' 512-byte fixed-length string buffer
' somewhere in here you would use FOpen or FCreate to open a file
Bytes% = 512 ' write 512 bytes
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL FWrite(Handle%, DSeg%, Dofs%, Bytes%, BytesWritten%, ErrCode%)
IF ErrCode% THEN PRINT "Error writing to file"
Name: GetAttrF
Type: Disk / DOS
Description:
Returns the attribute of a file matched by FindFirstF or FindNextF. The
attribute may be any combination of the following:
0 normal file
2 hidden file
4 system file
16 subdirectory
32 (archive bit)
The archive bit is used by some backup programs to detect whether a file
has been backed up or not. Generally you should simply ignore it.
Decoding the attribute can be done with the AND operator (see example).
Example:
CALL GetAttrF(Attr%)
IF (Attr% AND 31) = 0 THEN
PRINT "Normal file"
ELSE
IF Attr% AND 2 THEN PRINT "Hidden file"
IF Attr% AND 4 THEN PRINT "System file"
IF Attr% AND 16 THEN PRINT "Subdirectory"
END IF
Name: GetCRT
Type: Video / BIOS
Description:
Tells you what kind of display is being used. The returned value will be
zero if monochrome or nonzero if color. Note that this routine cannot
detect if a monochrome monitor is being used with a CGA card, in which
case a false "color" will be returned.
Example:
CALL GetCRT(ColorDisplay%)
IF ColorDisplay% THEN
PRINT "A color display is being used"
ELSE
PRINT "A monochrome display is being used"
END IF
Name: GetExtM
Type: Miscellaneous / AT BIOS
Description:
Gets the amount of extended memory available. This routine requires the
AT BIOS (only ATs can have extended memory) and should not be used with
PC or XT computers.
Example:
CALL GetExtM(KBytes%)
PRINT KBytes%; "kilobytes of extended memory"
Name: GetKbd
Type: Input / CLONE
Description:
Gets the state of the keyboard toggles. The associated variable will be
nonzero if the toggle is on or zero if it is off.
Example:
CALL GetKbd(Insert%, CapsLock%, NumLock%, ScrollLock%)
IF Insert% THEN PRINT "Insert mode is on"
IF CapsLock% THEN PRINT "Caps Lock is on"
IF NumLock% THEN PRINT "The keypad is in numeric mode"
IF ScrollLock% THEN PRINT "Scroll Lock is on"
Name: GetDateF
Type: Disk / DOS
Description:
Gets the date of a file matched by FindFirstF or FindNextF.
Related routines:
FindFirstF, FindNextF, GetAttrF, GetNameF, GetSizeF, GetTimeF
Example:
CALL GetDateF(Mnth%, Day%, Year%)
' The month variable isn't spelled "Month" because there's already
' a routine by that name and QB would get upset.
Name: GetDOSv
Type: Miscellaneous / DOS
Description:
Gets the DOS version. The major part of the version number is returned in
the first parameter, the minor part in the second. DOS 2.11, for
instance, would return "MajVer% = 2" and "MinVer% = 11".
Example:
CALL GetDOSv(MajVer%, MinVer%)
Name: GetDrv
Type: Disk / DOS
Description:
Gets the default drive. The result string must be initialized to at least
one character.
Example:
Drive$ = "x:"
CALL GetDrv(Drive$)
Name: GetFAttr
Type: Disk / DOS
Description:
Gets the attribute of a file. This attribute may be any combination of
the following:
0 normal file
2 hidden file
4 system file
16 subdirectory
32 (archive bit)
The archive bit is used by some backup programs to detect whether a file
has been backed up or not. Generally you should simply ignore it.
Decoding the attribute can be done with the AND operator (see example).
Example:
CALL GetFAttr(File$ + CHR$(0), Attr%)
IF (Attr% AND 31) = 0 THEN
PRINT "Normal file"
ELSE
IF Attr% AND 2 THEN PRINT "Hidden file"
IF Attr% AND 4 THEN PRINT "System file"
IF Attr% AND 16 THEN PRINT "Subdirectory"
END IF
Name: GetFDate
Type: Disk / DOS
Description:
Gets the date of a file. If there is no such file, the month variable
will be set to negative one.
Example:
CALL GetFDate(File$ + CHR$(0), Mnth%, Day%, Year%)
' The month variable isn't spelled "Month" because there's already
' a routine by that name and QB would get upset.
Name: GetFTime
Type: Disk / DOS
Description:
Gets the time of a file. The hour is in 24-hour format (0-23) and will be
set to negative one if there is no such file. The seconds are rounded to
the next lower even number, due to the way DOS stores the time.
Example:
CALL GetFTime(File$ + CHR$(0), Hour%, Minute%, Second%)
Name: GetKey
Type: Keyboard / BIOS
Description:
Waits until one of a specified list of keys is pressed and returns that
key in uppercase. If the key list is null, the first key pressed will be
returned. You must initialize the return string to at least one
character.
Example:
PRINT "Would you like to try again (Y/N)? ";
GoodKey$ = "YN"
Ky$ = "x"
CALL GetKey(GoodKey$, Ky$)
Name: GetLIMm
Type: Miscellaneous / BIOS
Description:
Gets the status of expanded memory. The number of total pages and number
of free pages are returned (a page is 16 Kbytes). Zeros will be returned
if no expanded memory is installed.
Example:
CALL GetLIMm(TotalPages%, FreePages%)
IF TotalPages% THEN
PRINT "Expanded memory is installed."
PRINT " Total 16K pages:"; TotalPages%
PRINT " Free 16K pages:"; FreePages%
ELSE
PRINT "No expanded memory is available."
END IF
Name: GetLine
Type: Video / ANY
Description:
Gets a specified line (row) from a saved screen into a string. The screen
may have been saved with one of the ScrSave routines, or with GetScreen
provided that full 80-column rows were saved. The result will have the
colors and trailing spaces removed, so it will be a printable text string.
Example:
DIM Buffer AS STRING * 4000 ' 4,000 bytes for one saved screen
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL ScrSave(DSeg%, DOfs%)
OPEN "SCREEN.TXT" FOR OUTPUT AS #1
RowText$ = SPACE$(80)
FOR Row% = 1 TO 25
CALL GetLine(VARSEG(Buffer), VARPTR(Buffer), Row%, RowText$, RLen%)
PRINT #1, LEFT$(RowText$, RLen%)
NEXT
CLOSE #1
' saves the screen to the text file SCREEN.TXT
Name: GetNameF
Type: Disk / DOS
Description:
Gets the name of a file matched by FindFirstF or FindNextF. The return
string must be initialized to at least 12 characters. The file name will
not include a drive or subdirectory specification.
Related routines:
FindFirstF, FindNextF, GetAttrF, GetDateF, GetSizeF, GetTimeF
Example:
FileName$ = SPACE$(12)
CALL GetNameF(FileName$, FLen%)
FileName$ = LEFT$(FileName$, FLen%)
Name: GetScreen
Type: Video / CLONE
Description:
Saves any part of any display page. You specify the upper left corner and
lower right corner of the area to save, the display page to save, a
buffer, and the screen mode. The display page should be zero for MDAs or
if you are not using paging. The screen mode should be zero for old CGA
displays that have problems with "snow". Otherwise, make it nonzero for
the best speed.
To calculate the necessary buffer size, use the following:
Bytes% = (BottomRow% - TopRow% + 1) * (RightCol% - LeftCol% + 1) * 2
Example:
DIM Buffer AS STRING * 4000 ' enough room for a full 80x25 screen
' presumeably your code goes here
TopRow% = 1 ' upper left corner
LeftCol% = 1
BottomRow% = 12 ' lower right corner
RightCol% = 80
Page% = 0 ' display page zero
ScrMode% = -1 ' no snow suppression
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL GetScreen(DSeg%, DOfs%, TopRow%, LeftCol%, BottomRow%, RightCol%,
Page%, ScrMode%)
' The CALL should actually be on a single line. It's split up just so
' it'll fit in 80 columns. This example saves the top half of the screen.
Name: GetSizeF
Type: Disk / DOS
Description:
Gets the size of a file matched by FindFirstF or FindNextF. You must
calculate the actual size from the two integers returned, since the size
can be larger than will fit into a single integer.
Example:
CALL GetSizeF(SizeLow%, SizeHigh%)
FileSize& = (SizeHigh% - (SizeLow% < 0)) * 65536& + CLNG(SizeLow%)
Name: GetSub
Type: Disk / DOS
Description:
Gets the default subdirectory on the current drive. The returned string
must be initialized to at least 64 characters. It will not be started by
a backslash, so you should add one if you want it.
Example:
SubDir$ = SPACE$(64)
CALL GetSub(SubDir$, SLen%)
SubDir$ = "\" + LEFT$(SubDir$, SLen%)
Name: GetTimeF
Type: Disk / DOS
Description:
Gets the time of a file matched by FindFirstF or FindNextF. The hour is
returned in 24-hour (0-23) format.
Related routines:
FindFirstF, FindNextF, GetAttrF, GetDateF, GetNameF, GetSizeF
Example:
CALL GetTimeF(Hour%, Minute%, Second%)
Name: InsChr
Type: Video / CLONE
Description:
Inserts a space at the specified screen position. The character
previously at that position and all characters to the right of it on the
same row will be shifted right to make room. This works only in text mode
(SCREEN 0) on display page zero.
Example:
Row% = CSRLIN
Col% = POS(0)
CALL InsChr(Row%, Col%) ' insert a space at the cursor
Name: Int2Date
Type: Miscellaneous / ANY
Description:
Uncompresses a date that was compressed by Date2Int. The year will be
returned in four-digit format (1900-2026).
Example:
CALL Int2Date(Mnth%, Day%, Year%, SqueezedDate%)
' we use Mnth% instead of Month% since there is a Month routine in ADVBAS
' and QuickBASIC doesn't like variables to share names with routines
Name: Int2Time
Type: Miscellaneous / ANY
Description:
Uncompresses a time that was compressed by Time2Int. The seconds will be
an even value (rounded down) due to the storage format used.
Example:
CALL Int2Time(Hour%, Minute%, Second%, SqueezedTime%)
Name: KeyPress
Type: Keyboard / BIOS
Description:
Tells whether a key is waiting in the keyboard buffer. The return value
is nonzero if a key is ready to be processed.
Example:
DO
CALL KeyPress(KeyHit%)
LOOP UNTIL KeyHit%
Ky$ = INKEY$
Name: LoCase
Type: String / ANY
Description:
Converts the letters in a string to lowercase. This is much faster than
the LCASE$ function provided by QuickBASIC.
Example:
CALL LoCase(St$)
Name: LRotate
Type: String / ANY
Description:
Rotates the characters in a string left. All characters are moved left
once, with the original leftmost character ending up on the right end of
the resulting string. This routine is useful for rotating queues and
character-graphics animation or marquee displays.
Example:
St$ = "12345"
CALL LRotate(St$) ' the result will be "23451"
Name: MakeSub
Type: Disk / DOS
Description:
Creates a subdirectory. A nonzero error code will be returned if it isn't
possible to create the subdirectory.
Example:
CALL MakeSub(SubDir$ + CHR$(0), ErrCode%)
IF ErrCode% THEN
PRINT "Error: unable to create subdirectory "; SubDir$
END IF
Name: MakeWindow
Type: Video / CLONE
Description:
Displays a pop-up window. You may choose from a variety of frame types
and window types. A window label may optionally be displayed as well.
The window frame is drawn -outside- of the window you've specified, so be
sure to allow extra room for the frame. Normal windows require one space
around on each side. Shadowed windows require an extra two columns on the
left and bottom sides.
Four types of windows may be displayed:
0 normal the window pops onto the screen
1 growing the window "explodes" onto the screen
2 shadowed the window is "shadowed" for a 3-D effect
3 growing/shadowed the window is both growing and shadowed
Five types of frames may be chosen:
0 none spaces
1 single single lines
2 double double lines
3 2v, 1h double vertical lines and single horizontal lines
4 1v, 2h single vertical lines and double vertical lines
Example:
TopRow% = 5 ' top left corner
LeftCol% = 5
BottomRow% = 20 ' bottom left corner
RightCol% = 79
Label$ = "Test Window" ' this would be "" for no label
Frame% = 1 ' frame type (single lines)
WindType% = 3 ' window type (growing/shadowed)
Fore% = 7 ' foreground color (white)
Back% = 0 ' background color (black)
Page% = 0 ' display page
CALL MakeWindow(LeftCol%, TopRow%, RightCol%, BottomRow%, Label$,
Frame%, WindType%, Fore%, Back%, Page%)
' The above CALL should be on one line in your program and is only
' divided here so it'll fit on your display or printer.
' NOTE that the coordinates are specified in Column, Row format rather
' than the more ordinary Row, Column format (sorry about that!)
Name: MDelChr
Type: Video / BIOS
Description:
Deletes the character at the current cursor position. The delete
operation affects only the area of the screen defined by MWindow.
Example:
CALL MDelChr
Name: MInsChr
Type: Video / BIOS
Description:
Inserts a space at the current cursor position. The insert operation
affects only the area of the screen defined by MWindow.
Example:
CALL MInsChr
Name: MmButton
Type: Input / BIOS
Description:
Gets the state of the mouse buttons. If a button is currently being held
down, a nonzero value will be returned in the appropriate variable. See
also the MmClick routine.
Example:
CALL MmButton(LeftButton%, RightButton%)
IF LeftButton% THEN PRINT "The left button is being pressed."
IF RightButton% THEN PRINT "The right button is being pressed."
Name: MmCheck
Type: Input / BIOS
Description:
Tells whether a mouse is installed. If not, zero is returned. If so, the
number of buttons that the mouse has is installed.
Example:
CALL MmCheck(Mouse%)
IF Mouse% THEN
PRINT "A mouse with"; Mouse%; "buttons is present."
ELSE
PRINT "No mouse is available."
END IF
Name: MmClick
Type: Input / BIOS
Description:
Tells which mouse buttons have been pressed since you last used this
routine. The number of times each button has been pressed is returned.
See also the MmButton routine.
Example:
CALL MmClick(LeftButton%, RightButton%)
IF LeftButton% THEN PRINT "The left mouse button was pressed."
IF RightButton% THEN PRINT "The right mouse button was pressed."
Name: MmCursorOn
Type: Input / BIOS
Description:
Makes the mouse cursor visible.
Example:
CALL MmCursorOn
Name: MmCursorOff
Type: Input / BIOS
Description:
Makes the mouse cursor invisible. It will still be there and will
function normally, but it won't be displayed.
Example:
CALL MmCursorOff
Name: MmGetLoc
Type: Input / BIOS
Description:
Gets the location of the mouse cursor. This is returned as a value based
on a 640x200 graphics screen. If you are in an 80x25 text mode, divide
both the columns and the rows by eight to compensate, and add one to each
since text-mode coordinates start at (1,1). If you're in the 320x200
graphics mode, divide the columns by two. If you're in 640x200 graphics
mode, of course, the numbers are fine as-is.
Example:
CALL MmGetLoc(Column%, Row%)
Column% = Column% \ 8 + 1 ' convert from 0-639 to 1-80
Row% = Row% \ 8 + 1 ' convert from 0-199 to 1-25
LOCATE Row%, Column%
PRINT "+";
Name: MmSetLoc
Type: Input / BIOS
Description:
Sets the location of the mouse cursor. The same 640x200 format as for
MmGetLoc (see) is used.
Example:
Row% = CSRLIN * 8 - 4 ' convert from 1-25 to 0-199
Column% = POS(0) * 8 - 4 ' convert from 1-80 to 0-639
CALL MmSetLoc(Column%, Row%)
Name: MmSetRange
Type: Input / BIOS
Description:
Sets the range for the mouse cursor, which will not be able to move
outside the specified rectangle. The same 640x200 format as for MmGetLoc
(see) is used.
Example:
LeftCol% = 40 ' top left corner
TopRow% = 10
RightCol% = 600 ' bottom right corner
BottomRow% = 190
CALL MmSetRange(LeftCol%, TopRow%, RightCol%, BottomRow%)
Name: MLoad
Type: Disk / DOS
Description:
A fast replacement for the BLOAD statement. The file is loaded into the
area of memory from which it came when BSAVEd.
Example:
File$ = "PICTURE.BAS"
CALL MLoad(File$ + CHR$(0))
Name: Month
Type: Miscellaneous / ANY
Description:
Gets the name of the month, given the month number. You must initialize
the return string to at least nine characters.
Example:
FOR MonthNum% = 1 to 12
Mnth$ = SPACE$(9)
CALL Month(Mnth$, MLen%, MonthNum%)
Mnth$ = LEFT$(Mnth$, MLen%)
PRINT "Month"; MonthNum%; "is "; Mnth%
NEXT
' This prints the name of each month.
' The variable MONTH$ isn't used in order to avoid conflicts with
' the routine named MONTH (QuickBASIC gets picky there).
Name: MPrintC
Type: Video / BIOS
Description:
Sends a character to the display using (mostly) DOS output. This allows
use of ANSI.SYS and supports output redirection. The output will remain
in the window defined by MWindow. The new cursor position is returned so
that you can tell QB about it using LOCATE. Note that the coordinates are
returned in reverse order!
Example:
CALL MPrintC(Ch$, Column%, Row%)
LOCATE Row%, Column%
Name: MPrint
Type: Video / BIOS
Description:
Sends a string to the display using (mostly) DOS output. This allows the
use of ANSI.SYS and supports output redirection. The output will remain
in the window defined by MWindow. The new cursor position is returned so
that you can tell QB about it using LOCATE. Note that the coordinates are
returned in reverse order!
Example:
CALL MPrint(St$, Column%, Row%)
LOCATE Row%, Column%
Name: MultiAND
Type: String / ANY
Description:
Performs an arithmetic AND operation on each character in a string. See
your BASIC manual for a discussion of the AND operator.
Example:
CALL MultiAND(St$, BitMask%)
Name: MultiOR
Type: String / ANY
Description:
Performs an arithmetic OR operation on each character in a string. See
your BASIC manual for a discussion of the OR operator.
Example:
CALL MultiOR(St$, SetBits%)
Name: MultiXOR
Type: String / ANY
Description:
Performs an arithmetic XOR operation on each character in a string. See
your BASIC manual for a discussion of the XOR operator. Note that this
will also function as a "MultiNOT" if you use BitMask% = 255.
Example:
CALL MultiXOR(St$, BitMask%)
Name: MWindow
Type: Video / BIOS
Description:
Defines the screen area for the MPrint, MPrintC, MInsChr and MDelChr
routines. The output from those functions will be confined to the
specified window. After using MWindow, you should make sure that the
cursor is inside the defined area with LOCATE. Do not define a window of
less than two rows.
Example:
CALL MWindow(LeftColumn%, TopRow%, RightColumn%, BottomRow%)
LOCATE TopRow%, LeftColumn%
Name: PrintScreen
Type: Miscellaneous / BIOS
Description:
Prints a copy of the screen on the first printer device. This is just
like using Shift-PrtSc (or Print Screen) from your keyboard. It can also
display CGA graphics if you install the GRAPHICS.COM program that came
with your copy of MS-DOS.
Example:
CALL PrintScreen
Name: PutScreen
Type: Video / CLONE
Description:
Restores a saved screen area to any part of any display page. You specify
the upper left corner and lower right corner of the area to which to
restore, the display page to which to restore, the saved screen buffer,
and the screen mode. The display page should be zero for MDAs or if you
are not using paging. The screen mode should be zero for old CGA displays
that have problems with "snow". Otherwise, make it nonzero for the best
speed.
Example:
' presumeably you used GetScreen before this, saving it to Buffer...
TopRow% = 1 ' upper left corner
LeftCol% = 1
BottomRow% = 12 ' lower right corner
RightCol% = 80
Page% = 0 ' display page zero
ScrMode% = -1 ' no snow suppression
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL PutScreen(DSeg%, DOfs%, TopRow%, LeftCol%, BottomRow%, RightCol%,
Page%, ScrMode%)
' The CALL should actually be on a single line. It's split up just so
' it'll fit in 80 columns. This example saves the top half of the screen.
Name: QPrint
Type: Video / CLONE
Description:
Displays a string directly to the screen, very quickly, using the colors
that are already on the screen. Control characters are not translated and
will always show up as graphics characters. Display page zero is used.
This routine does not update the cursor position, and must be used in text
modes (SCREEN 0).
Related routines:
XqPrint
Example:
St$ = "This is a test of fast screen printing"
Row% = 10
Col%=20
CALL QPrint(St$, Row%, Col%)
Name: ReadBitF
Type: Miscellaneous / ANY
Description:
Provides support for arrays of arbitrary bit length (1-8 bits). The index
may range 0-65,535 (use a long integer for indices of over 32,767).
Example:
DSeg% = VARSEG(ArrayBuffer)
DOfs% = VARPTR(ArrayBuffer)
CALL ReadBitF(DSeg%, DOfs$, Indx&, BitLength%, Result%)
Name: ReColor
Type: Video / CLONE
Description:
Converts one color to another, across the entire screen. Text modes
(SCREEN 0) are required. Define the old and new colors using the CalcAttr
routine.
Example:
CALL ReColor(OldColor%, NewColor%)
Name: ResetPoint
Type: Video / BIOS
Description:
Resets a point. This provides support for 80x50 graphics in text mode
(SCREEN 0).
Related routines:
SetPoint, TestPoint
Example:
CALL ResetPoint(Column%, Row%)
Name: Reverse
Type: String / ANY
Description:
Reverses the order of the characters in a string. This can be used with
INSTR to find the last occurrence of a substring within a string, for
instance.
Example:
St$ = "This is a test"
CALL Reverse(St$)
PRINT St$
Name: RRotate
Type: String / ANY
Description:
Rotates the characters in a string right. All characters are moved right
once, with the original rightmost character ending up on the left end of
the resulting string. This routine is useful for rotating queues and
character-graphics animation or marquee displays.
Example:
St$ = "12345"
CALL RRotate(St$) ' the result will be "51234"
Name: Scroll
Type: Video / BIOS
Description:
Scrolls any selected part of the screen up by a specified number of lines.
If you tell it to scroll zero lines, the specified area will be cleared.
Example:
TopRow% = 1
LeftCol% = 1
BottomRow% = 25
RightCol% = 80
Times% = 2
CALL Scroll(LeftCol%, TopRow%, RightCol%, BottomRow%, Times%)
' scrolls the entire screen up two lines
Name: ScrRest
Type: Video / CLONE
Description:
Restores a saved screen to the display. Requires text mode (SCREEN 0) and
uses display page zero.
Example:
' presumeably you used ScrSave before this, saving it to Buffer...
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL ScrRest(Dseg%, DOfs%)
Name: ScrSave
Type: Video / CLONE
Description:
Saves the screen to a buffer. Requires text mode (SCREEN 0) and uses
display page zero. The buffer must hold at least 4,000 bytes.
Example:
REDIM Buffer AS STRING * 4000
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL ScrSave(DSeg%, DOfs%)
Name: ScrRestP, ScrRestPD, ScrSaveP, ScrSavePD
Type: Video / CLONE
Description:
These routines are variations on ScrRest and ScrSave. All of them allow
you to specify a display page (use zero on MDAs). The ones with the "D"
suffix do not provide snow suppression, unlike the other routines, but
they are much faster. Snow suppression is only required on some older
CGAs and will not affect other displays.
Example:
' presumeably you used one of the ScrSave routines before this...
Page% = 0
DSeg% = VARSEG(Buffer)
DOfs% = VARPTR(Buffer)
CALL ScrRestPD(Dseg%, DOfs%, Page%)
Name: SetComm
Type: Miscellaneous / CLONE
Description:
Sets the parameters for an open communications device. You don't have to
close the device to change the parameters, so you don't have to risk
losing your connection. The baud rate can also be set much higher than
BASIC normally allows, although the useful speeds will depend on your
particular hardware and program design.
The number of bits per second ("baud rate") is specified as follows:
Baud Use Baud Use
----- --- ------ ---
300 0 9,600 5
600 1 19,200 6
1,200 2 38,400 7
2,400 3 57,600 8
4,800 4
Example:
OPEN "R", 1, "COM1:300,E,7,1,RS,CS,DS"
CommPort% = 1 ' may be 1 or 2
Baud% = 6 ' see chart above (here, it means 19,200 baud)
Parity% = 0 ' use 0 for None, 1 for Odd, 2 for Even
WordLength% = 8 ' may be 7 or 8
StopBits% = 1 ' may be 1 or 2
CALL SetComm(CommPort$, Baud%, Parity%, WordLength%, StopBits%)
' set COM1 to 19200 baud, No parity, 8 bit words, and 1 stop bit.
Name: SetDrv
Type: Disk / DOS
Description:
Sets the default drive.
Example:
Drive$ = "C"
CALL SetDrv(Drive$)
Name: SetFAttr
Type: Disk / DOS
Description:
Sets a file attribute. Attributes may be as follows:
0 normal file or subdirectory
2 hidden file or subdirectory
4 system file (don't use unless you know what you're doing)
Example:
Attr% = 2
CALL SetFAttr(File$ + CHR$(0), Attr%) ' hide a file
Name: SetFTD
Type: Disk / DOS
Description:
Sets the time and date of a file. The year may be two or four digits.
The hour is specified in 24-hour format, with midnight being 24 rather
than the usual 0. The seconds will be rounded down to the closest even
number by DOS. The month will be set to -1 if there was an error.
Example:
CALL SetFTD(File$ + CHR$(0), Mnth%, Day%, Year%, Hour%, Minute%, Second%)
IF Mnth% = -1 THEN PRINT "Error: No such file as "; File$
Name: SetMatI
Type: Miscellaneous / ANY
Description:
Sets every element of an integer array to a specified value.
Example:
Lo% = LBOUND(Array%)
Hi% = UBOUND(Array%)
Elements% = Hi% - Lo% + 1
Value% = 100
DSeg% = VARSEG(Array%(Lo%))
DOfs% = VARPTR(Array%(Lo%))
CALL SetMatI(DSeg%, DOfs%, Elements%, Value%)
' we just initialized the entire array to 100
Name: SetKbd
Type: Input / CLONE
Description:
Sets the state of the keyboard toggles (keys which switch on and off). If
you provide a nonzero value, the state is turned on. The state is turned
off if the value given is zero. If you change the keyboard state, you
should restore the original state before your program exits.
Related routines:
GetKbd
Example:
Insert% = 1 ' turn on insert mode
CapsLock% = 0 ' turn off caps lock
NumLock% = 0 ' turn off num lock
ScrollLock% = 0 ' turn off scroll lock
CALL SetKbd(Insert%, CapsLock%, NumLock%, ScrollLock%)
Name: SetPoint
Type: Video / BIOS
Description:
Sets a point. This provides support for 80x50 graphics in text mode
(SCREEN 0).
Related routines:
ResetPoint, TestPoint
Example:
Y% = 24
FOR X% = 0 TO 79
CALL SetPoint(X%, Y%)
NEXT X%
' we just drew a horizontal line across the middle of the screen
Name: SetSub
Type: Disk / DOS
Description:
Sets the default subdirectory. A nonzero error code will be returned if
the specified subdirectory doesn't exist.
Example:
CALL SetSub(SubDir$ + CHR$(0), ErrCode%)
IF ErrCode% THEN PRINT "Error: No such subdirectory as "; SubDir$
Name: ShiftL
Type: Miscellaneous / ANY
Description:
This is a SHL operator. It shifts all the bits in an integer left by a
specified number of times. The vacated bit positions are zeroed. For
non-negative numbers, this is an efficient way to multiply by a power of
two. Each time you shift left, you effectively multiply the previous
value by two.
Example:
Value% = 47
Count% = 3
CALL ShiftL(Value%, Count%)
' the result will be 47 * 2^3, i.e., 376
Name: ShiftR
Type: Miscellaneous / ANY
Description:
This is a SHR operator. It shifts all the bits in an integer right by a
specified number of times. The vacated bit positions are zeroed. For
non-negative numbers, this is an efficient way to divide by a power of
two. Each time you shift left, you effectively divide the previous value
by two.
Example:
Value% = 47
Count% = 3
CALL ShiftR(Value%, Count%)
' the result will be 47 \ 2^3, i.e., 5
Name: Soundex
Type: String / ANY
Description:
Calculates the Soundex code for a specified string. The Soundex code can
be used for comparing strings to see if they sound alike. Matching is
somewhat loose, which allows very nicely for regional pronunciation but
also may give matches on some unexpected words.
The Soundex code is generated by removing all the vowels from a word and
then giving similar-sounding letters (like "t" and "d") the same number.
You can compare the results with a target Soundex value using ordinary
string comparisons. If the words are not too long, you could store them
conveniently by converting them to long integers. This will allow you to
store a Soundex code of up to nine digits (which allows for words longer
than nine characters, since vowels are ignored) in only four bytes (which
is the amount of space a long integer requires).
Example:
INPUT "Check the spelling of what word"; Word$
SoundexCode$ = Word$
CALL Soundex(Word$, SoundexCode$, SLen%)
SoundexCode$ = LEFT$(SoundexCode$, SLen%)
' Now you would search through your word list for words which have the
' same Soundex code as SoundexCode$ (might check for null code first).
Name: Strip
Type: String / ANY
Description:
Removes all occurrences of a specified character from a string.
Example:
St$ = "12 - 2 = 10"
Ch$ = " "
CALL Strip(St$, Ch$, SLen%)
St$ = LEFT$(St$, SLen%)
' the result will be "12-2=10"
Name: StripBlanks
Type: String / ANY
Description:
Removes "white space" from either the left side, the right side, or both
sides of a string. White space consists of blanks and control codes.
Specify 1 to strip the left side, 2 for the right side, or 3 for both.
This routine differs from the QuickBASIC functions LTRIM$ and RTRIM$ in
that it removes control codes as well as blanks. It is also much faster.
Example:
St$ = " This is a test "
Side% = 3 ' strip blanks from both sides
CALL StripBlanks(St$, Side%, SLen%)
St$ = LEFT$(St$, SLen%)
' the result will be "This is a test"
Name: StripRange
Type: String / ANY
Description:
Removes all characters within a specified range from a string.
Example:
St$ = "ALL uppercase letters will be G-O-N-E gone"
Lo% = ASC("A")
Hi% = ASC("Z")
CALL StripRange(St$, Lo%, Hi%, SLen%)
St$ = LEFT$(St$, SLen%)
' the result will be " uppercase letters will be --- gone"
Name: SubExist
Type: Disk / DOS
Description:
Sees if a specified subdirectory exists. You may include a drive
specification in the subdirectory name.
Example:
CALL SubExist(SubDir$ + CHR$(0), Valid%)
IF Valid% THEN
PRINT "Subdirectory "; SubDir$; " already exists"
ELSE
PRINT "Subdirectory "; SubDir$; " does not exist"
END IF
Name: TestPoint
Type: Video / BIOS
Description:
Tests a point. This provides support for 80x50 graphics in text mode
(SCREEN 0). A nonzero value will be returned if the point is set.
Related routines:
ResetPoint, SetPoint
Example:
X% = 39
Y% = 24
CALL TestPoint(X%, Y%, PointSet%)
IF PointSet% THEN
PRINT "The point is set"
ELSE
PRINT "The point is reset"
END IF
Name: Time2Int
Type: Miscellaneous / ANY
Description:
Compresses a time into an integer. Some accuracy will be lost in the
seconds value, which will be made even (odd numbers are rounded down).
Hours should be specified using military time (0-23) to avoid ambiguity.
Related routines:
Date2Int, Int2Date, Int2Time, TimeN2S, TimeS2N
Example:
CALL(Hour%, Min%, Sec%, SqzTime%)
Name: TimeN2S
Type: String / ANY
Description:
Converts a time from numeric form to a string. You must reserve at least
eight characters for the string.
Related routines:
DateN2S, DateS2N, TimeS2N
Example:
Hour% = 13 ' 1:30:08 pm
Min% = 30
Sec% = 8
TimeSt$ = SPACE$(8)
CALL TimeN2S(Hour%, Min%, Sec%, TimeSt$)
' the result will be "13:30:08"
Name: TimeS2N
Type: String / ANY
Description:
Converts a time from a string to numeric form. The seconds part is
optional and will be returned as zero if not in the string.
Example:
TimeSt$ = "13:09:42"
CALL TimeS2N(Hour%, Min%, Sec%, TimeSt$)
Name: TInstr
Type: String / ANY
Description:
Returns the position of the first occurrence of a specified type of
character within a string. You may combine the following character types
by adding their codes (which also allows you to search for the opposite of
a specified type).
Code Char. Type Specifications
1 Alphabetic A-Z, a-z
2 Numeric 0-9
4 Symbolic (anything not covered by other types)
8 Control (control codes: ASCII 0-31, 127)
16 Graphics (PC graphics codes: 128-255)
32 Blank (a blank space, ASCII 32)
Example:
ChrType% = 2 ' seek numeric character
St$ = "Mesa, AZ 85204"
CALL TInstr(St$, ChrType%, Place%)
ZipCode$ = MID$(St$, Place%)
' the result will be "85204"
Example:
ChrType% = 1 + 2 + 4 + 8 + 16 ' seek non-blank character
CALL TInstr(St$, ChrType%, Place%)
IF Place% THEN
PRINT "The first non-blank character is at location"; Place%; "."
ELSE
PRINT "The string contains no non-blank characters"
END IF
Name: UpCase
Type: String / ANY
Description:
Capitalizes every letter in a string. This is much faster than the UCASE$
function that comes with QuickBASIC.
Example:
CALL UpCase(St$)
Name: WeekDay
Type: Miscellaneous / DOS
Description:
Returns an integer which indicates the day of the week, Sunday through
Saturday. The example shows how to convert the result into a string.
Example:
CALL WeekDay(Day%)
DayLen% = VAL(MID$("3346535", Day%, 1))
DayLoc% = ASC(MID$("ADGKQVY", Day%, 1)) - 64 ' string must be uppercase
DayName$ = MID$("SunMonTuesWednesThursFriSatur", DayLoc%, DayLen%) + "day"
PRINT "Today is "; DayName$
Name: WriteBitF
Type: Miscellaneous / ANY
Description:
Provides support for arrays of arbitrary bit length (1-8 bits). The index
may range 0-65,535 (use a long integer for indices of over 32,767). The
numbers are compressed into an ordinary integer array. Since each integer
can hold 16 bits, you can calculate the size to which to DIMension the
integer array as follows:
ArraySize% = CINT((BitArraySize% * BitLength%) / 16! + .5)
Related routines:
ReadBitF
Example:
REDIM Array%(1 TO ArraySize%)
DSeg% = VARSEG(Array%(1))
DOfs% = VARPTR(Array%(1))
CALL WriteBitF(DSeg%, DOfs%, Index%, BitLength%, Value%)
Name: Xlate
Type: String / ANY
Description:
Translates each character of a string using a specified table. The
translation table is given as a 256-character string, where each string
location contains the value to which to convert the corresponding ASCII
code (CHR$(0) is translated to MID$(XlateTable$, 1, 1), and so on).
Example:
XlateTable$ = ""
FOR Init% = 0 TO 255 ' set up do-nothing table
XlateTable$ = XlateTable$ + CHR$(Init%)
NEXT
FOR Init% = ASC("A") TO ASC("Z") ' uppercase to lowercase
MID$(XlateTable$, Init% + 1, 1) = CHR$(Init% + ASC("a") - ASC("A"))
NEXT
' The above setup routine would be at the start of your program.
' The below routine runs a string through the translator, in this example
' converting uppercase characters to lowercase.
CALL Xlate(St$, XlateTable$)
Name: XmPrint
Type: Video / BIOS
Description:
Combines the Xlate and MPrintC routines. The specified character is run
through a translation table and printed to the screen (unless the result
is CHR$(0), in which case the character is not printed).
Related routines:
MPrintC, Xlate
Example:
CALL XmPrint(Ch$, XlateTable$, Col%, Row%)
LOCATE Row%, Col%
' Note that the row and column are -returned-, not initially specified.
' They are also in reverse order from the usual Microsoft format.
Name: XQPrint
Type: Video / CLONE
Description:
Displays a string directly to the screen, very quickly. Control codes are
not translated and will always show up as graphics characters. You must
specify which display page to use and the color (which is calculated by
the CalcAttr routine). This routine does not update the cursor position
and must be used in text mode (SCREEN 0).
Related routines:
QPrint, XQPrintD
Example:
St$ = "This is a test of fast screen printing"
Row% = 10
Col% = 20
Page% = 0
ForeGnd% = 0 ' let's use reverse video
BackGnd% = 7
CALL CalcAttr(ForeGnd%, BackGnd%, Attr%)
CALL XqPrint(St$, Row%, Col%, Attr%, Page%)
Name: XQPrintD
Type: Video / CLONE
Description:
Just like XQPrint, but writes directly to the screen without snow
suppression. This makes it much faster, but means that it will cause
flickering on some obsolete CGA displays.
Related routines:
QPrint, XQPrint
New file I/O routines
This contains some general information about the ADVBAS file I/O routines:
FClose, FCreate, FOpen, FRead, FSetEnd, FSetRec, and FWrite.
These routines essentially duplicate a number of existing BASIC statements.
They are useful, however, for a number of reasons. They provide you with
low-level control over the details of file input and output. They may be
readily used in subprograms, since they return error codes rather than
relying on error trapping. This is important, since BASIC error trapping
(ON ERROR GOTO) makes your program much larger and slower, and is not
designed for use within subprograms in any event.
These routines provide access to the file locking capabilities of MS-DOS 3.0
and above, allowing you to create programs which work properly on networks
and in multitasking environments. Unlike QuickBASIC, the routines will work
with older versions of DOS even if you use file locking, although of course
they won't provide the networking/multitasking capabilities that old DOS
versions lack.
When you open a file in BASIC, you give the file a number. From that point
on, you always refer to that file by the same number, until you CLOSE it.
With the ADVBAS routines, you don't give the file a number-- instead, the
number (a "handle") is returned to you by the routine. This frees you from
having to worry about whether the number you specified is already in use.
In BASIC, when you open a file for OUTPUT or RANDOM access, the file is
automatically created, or deleted and recreated if it already exists. The
ADVBAS routines will not automatically create (or delete) files unless you
use the FCreate routine. This helps guard against unexpectedly annihilating
existing files.
Like BASIC, you must CLOSE a file when you are finished using it. Unlike
BASIC, this is not done automatically for you when the program ends-- you
must use the FClose routine, or your file(s) may not be properly updated.
The ADVBAS file routines are not restricted to specific modes the way BASIC
is. You can use them on sequential or random files, text or binary files, or
for that matter, devices. Every time you read from or write to a file, the
file pointer is updated to point to the next file location (like BASIC
sequential files)... but if you prefer, you can set the file pointer to a
specific location (like BASIC random-access files).
The ADVBAS file routines do not provide critical error handling, which copes
with serious disk problems (such as leaving the drive door open on floppy
drives). They do support the critical error handler provided by BASIC when
you compile with error trapping turned on, however.
New file I/O routines
Here are the more common error codes returned by the file routines:
-1 Unable to read or write the entire record
2 File not found
3 Path not found
4 No handle available
5 Access denied
6 Invalid handle
15 Invalid drive specification
If you get a "no handle available" error, you have run out of room to open
files. You can increase this to some extent by adding an appropriate
"FILES=xx" statement to your CONFIG.SYS. If this doesn't help and you really
need to have all those files open at once, you can gain extra file handles by
using FClose on some of the predefined system file/device handles:
0 stdin standard input (do not close this one)
1 stdout standard output (do not close this one)
2 stderr standard error output (probably safe to close)
3 stdaux comm port #1 (usually safe to close)
4 stdprn printer port #1 (usually safe to close)
The comment "usually safe to close" means that this handle is not used by
QuickBASIC and can be closed and re-used by your program unless you have a
specific need to access that handle. QuickBASIC has its own communications
and printer handlers which do not rely on DOS, so it's almost always safe to
close handles 3 and 4, which will gain you access to two more file handles.
See your DOS manual for further information on files and CONFIG.SYS.
Bugs in BASIC Compilers
QuickBASIC 1.0:
If there is not enough memory when you try to execute the SHELL command, your
program will crash.
The error STRING FORMULA TOO COMPLEX appears erratically in some programs,
for no apparently good reason.
QuickBASIC 1.02:
This release solves the SHELL crash problem. Also, more control
characters are handled in the same manner as the BASIC interpreter. Many
miscellaneous problems have been fixed... but not the mysterious and deadly
STRING FORMULA TOO COMPLEX error.
QuickBASIC 2.0 - 3.0:
If your program uses error trapping, it must have at least one line number
in the program, even you normally only use labels. Otherwise the program
will crash if it runs into an error.
Screen paging doesn't work in QB 2.0.
If you have a REMark on the same line as a DATA statement, you'll get a
series of peculiar error messages.
Compiling programs which use libraries from the editor/environment produces
flaky code. This does not affect compiling from the command line, however.
Bugs in BASIC Compilers
QuickBASIC 4.0:
Dynamic arrays can't be passed to assembly routines in the standard manner.
This also affects static arrays, but only in the QB editor/environment. The
DYNPTR routine has been added to ADVBAS to solve this problem.
Compiling programs which use libraries from the editor/environment produces
excessively large programs. Instead of linking just the appropriate
routines, QuickBASIC links the entire library to your program. Due to the
syntax used, this can also cause the compilation to abort due to having too
many routines for the linker to cope with. This does not affect compiling
from the command line, however, provided that you use the normal syntax
instead of the bizarre syntax that the QB editor/environment uses.
When compiling programs which use libraries from the editor/environment, the
LIB path variable is ignored. This means that your .LIB files must be in the
directory in which you are compiling your program.
Serial communications is buggy. If you SHELL or do any of a number of other
things, QuickBASIC is liable to entirely forget about the existence of the
comm port(s). In fact, it essentially erases all knowledge of the comm ports
from the computer. This can be cured by rebooting the system.
QuickBASIC 4.1:
The communications problems have been fixed.
QuickBASIC 4.5:
The problems with compiling from the editor/environment have been fixed.
BASIC Bugs
You can create files that contain blank spaces using BASIC. This is a
problem, since DOS considers the space to be a delimiter, and is entirely
unable to cope with such files. Some archive and disk backup programs also
have trouble with files containing spaces. Be careful to screen out any
spaces before creating files! Note that this also applies to subdirectories,
which are really only a kind of specialized file.
If you convert a string to a number using the VAL function, you expect the
conversion process to end at the end of the string or at the first
non-numeric character. Unfortunately, BASIC does not consider spaces to be
non-numeric, with the result that a string like "256 12" is not converted to
256, as you would expect, but to 25612. Microsoft's representatives on
CompuServe do not consider this to be a bug, although it's hard to think of
an application in which such behavior might be appropriate.